<?php
/*
+--------------------------------------------------------------------------
|   Anwsion [#RELEASE_VERSION#]
|   ========================================
|   by Tatfook Network Team
|   (c) 2011 - 2012 Anwsion Software
|   http://www.anwsion.com
|   ========================================
|   Support: zhengqiang@gmail.com
|   
+---------------------------------------------------------------------------
*/

class notify_class extends AWS_MODEL
{
	//=========模型类别:model_type===================================================
	

	const CATEGORY_QUESTION = 1; //问题
	const CATEGORY_PEOPLE = 4; //人物
	const CATEGORY_CONTEXT = 7; //文字
	

	//=========操作标示:action_type==================================================
	

	const TYPE_PEOPLE_FOCUS = 101; //被人关注
	const TYPE_NEW_ANSWER = 102; //关注的问题增加了新回复
	const TYPE_COMMENT_AT_ME = 103; //有评论@提到我
	const TYPE_INVITE_QUESTION = 104; //被人邀请问题问题
	const TYPE_ANSWER_COMMENT = 105; //我的回复被评论
	const TYPE_QUESTION_COMMENT = 106; //我的回复被评论
	const TYPE_ANSWER_AGREE = 107;	//我的回复被赞同
	const TYPE_CONTEXT = 100; //纯文本通知
	

	//===============================================================================
	
	public $user_id;
	public $notify_actions = array();
	public $notify_action_details;

	public function setup()
	{
		$this->user_id = USER::get_client_uid();
		
		if($this->notify_action_details = AWS_APP::config()->get('notification')->action_details)
		{		
			foreach ($this->notify_action_details as $key => $val)
			{
				$this->notify_actions[] = $key;
			}
		}
	}

	/**
	 * 发送通知
	 * Enter description here ...
	 * @param unknown_type $action_type	操作类型，使用notify_class调用TYPE
	 * @param unknown_type $uid			接收用户id
	 * @param unknown_type $data		附加数据
	 * @param unknown_type $model_type	可选，合并类别，使用notify_class调用CATEGORY
	 * @param unknown_type $source_id	可选，合并子ID
	 */
	public function send($sender_uid, $recipient_uid, $action_type, $model_type = 0, $source_id = 0, $data = array())
	{
		$recipient_uid = intval($recipient_uid);
		
		if($recipient_uid == 0)
		{
			return false;
		}
		
		if (! in_array($action_type, $this->notify_actions) && ($action_type > 0))
		{
			return false;
		}
		
		//以下动作不通知自己
		$nosend_user_actions = array(
			notify_class::TYPE_NEW_ANSWER,
			notify_class::TYPE_COMMENT_AT_ME,
			notify_class::TYPE_INVITE_QUESTION,
			notify_class::TYPE_ANSWER_COMMENT,
			notify_class::TYPE_QUESTION_COMMENT,
			notify_class::TYPE_ANSWER_AGREE
		);
		
		if (($recipient_uid == $this->user_id) && (in_array($action_type, $nosend_user_actions)))
		{
			return false;
		}
		
		if (! $this->check_notification_setting($recipient_uid, $action_type))
		{
			return false;
		}
		
		$notify_data = array(
			'sender_uid' => $sender_uid,
			'recipient_uid' => $recipient_uid,
			'action_type' => $action_type,
			'model_type' => $model_type,
			'source_id' => $source_id,
			'add_time' => time(),
			'read_flag' => 0,
			'data' => serialize($data),
		);
		
		$notification_id = $this->insert('notification', $notify_data);
		
		if ($notification_id)
		{
			$this->model("account")->increase_user_statistics(account_class::NOTIFICATION_UNREAD, 0, $recipient_uid);
			return $notification_id;
		}
		else
		{
			return false;	
		}
	}

	/**
	 * 获得通知列表
	 */
	public function list_notification($recipient_uid, $read_status = '', $limit = "0,20")
	{
		$notify_ids = $this->get_notification_list(false, $recipient_uid, $read_status, $limit);
		
		if(empty($notify_ids))
		{
			return array();
		}
		
		$ntlist = $this->get_notification_by_ids($notify_ids);

		if(empty($ntlist))
		{
			return array();
		}
		
		$unread_notifys = $this->get_unread_notification($recipient_uid);
		
		$unread_extends = array();
		
		if($unread_notifys)
		{
			foreach($unread_notifys as $key => $val)
			{
				if($val['model_type'] == self::CATEGORY_QUESTION)
				{
					$unread_extends[$val['model_type']][$val['source_id']][] = $val;
				}
			}
		}
		
		if ($ntlist)
		{
			foreach($ntlist as $key => $val)
			{
				if($val['read_flag'] > 0)	//已读条目不合并
				{
					continue;
				}
				
				if(count($unread_extends[$val['model_type']][$val['source_id']]) > 1)
				{
					$ntlist[$key]['extends'] = $unread_extends[$val['model_type']][$val['source_id']];
				}
			}
		}
		
		$list = array();
		
		//p($ntlist);die;
		if(!is_array($ntlist))
		{
			$ntlist=array();
		}
		foreach ($ntlist as $key => $notify)
		{
			$data = $notify['data'];
			
			if(empty($data))
			{
				continue;
			}
			
			$tmp = array();
				
			$tmp['notification_id'] = $notify['notification_id'];
			$tmp['model_type'] = $notify['model_type'];
			$tmp['action_type'] = $notify['action_type'];
			$tmp['read_flag'] = $notify['read_flag'];
			$tmp['add_time'] = $notify['add_time'];

			if ($data['from_uid'])
			{
				$userinfo = $this->model('account')->get_users_by_uid($data['from_uid']);
				$tmp['p_username'] = $userinfo['user_name'];
				$tmp['p_url'] = 'people/' . $tmp['p_username'];
			}
				
			$token = "notification_id-" . $notify['notification_id'];
				
			switch ($notify['model_type'])
			{
				case self::CATEGORY_QUESTION :
						
					$question_info = $this->model('question')->get_question_info_by_id($data['question_id']);
			
					if(empty($question_info))
					{
						unset($tmp);
						continue;
					}
			
					$tmp['title'] = $question_info['question_content'];
						
					//通知标识，评论标识，来源用户ID，答案集合&最后答案
					$querys = array();
					
					$querys[] = $token;
					
					if($notify['extends'])
					{
						$tmp['extend_count'] = count($notify['extends']);
						
						$answer_ids = array();
						
						$comment_type = array();
						
						foreach($notify['extends'] as $ex_key => $ex_notify)
						{
							if($ex_notify['action_type'] == 104)
							{
								$from_uid = $ex_notify['data']['from_uid']; 
							}
						
							if(($ex_notify['action_type'] == 106) || ($ex_notify['action_type'] == 103 && $ex_notify['data']['comment_type'] == 1))
							{
								$comment_type[] = '1';
							}
							
							if(($ex_notify['action_type'] == 105) || ($ex_notify['action_type'] == 103 && $ex_notify['data']['comment_type'] == 2))
							{
								$comment_type[] = '2';
							}
							
							if($ex_notify['data']['item_id'] > 0)
							{
								$answer_ids[] = $ex_notify['data']['item_id'];
							}
						}
						
						if($from_uid)
						{
							$querys[] = 'from_uid-' . $from_uid;
						}
						
						if($comment_type)
						{
							if(count(array_unique($comment_type)) == 1)
							{
								$querys[] = 'comment-' . array_pop($comment_type);
							}
							else if(count(array_unique($comment_type)) == 2)
							{
								$querys[] = 'comment-all';
							}
						}
						
						if($answer_ids)
						{
							$answer_ids = array_unique($answer_ids);
							
							asort($answer_ids);
							
							$querys[] = 'item_id-' . implode(',', $answer_ids) . '#answer_' . array_pop($answer_ids);
						}
					}
					else
					{
						if($notify['action_type'] == 104)
						{
							$querys[] = 'from_uid-' . $data['from_uid'];
						}
						
						if(($notify['action_type'] == 106) || ($notify['action_type'] == 103 && $data['comment_type'] == 1))
						{
							$querys[] = 'comment-1';
						}
						
						if(($notify['action_type'] == 105) || ($notify['action_type'] == 103 && $data['comment_type'] == 2))
						{
							$querys[] = 'comment-2';
						}
						
						if($data['item_id'])
						{
							$querys[] = 'item_id-' . $data['item_id'] . '#answer_' . $data['item_id'];
						}
					}
					
					$tmp['key_url'] = 'question/id-' . $data['question_id'] . '?' . implode('__', $querys);
			
					break;
				case self::CATEGORY_PEOPLE :
			
					if(empty($userinfo))
					{
						unset($tmp);
						continue;
					}
			
					$tmp['key_url'] = $tmp['p_url'] . '?' . $token;
			
					break;
				case self::CATEGORY_CONTEXT :
						
					$tmp['content'] = $data['content'];
						
					break;
			}
			
			if($tmp)
			{
				$list[] = $tmp;
			}
			else
			{
				$this->delete_notify($notify['notification_id']);
			}
		}
		
		return $list;
	}


	/**
	 * 检查指定用户的通知设置
	 * Enter description here ...
	 */
	public function check_notification_setting($recipient_uid, $action_type)
	{
		if (! in_array($action_type, $this->notify_actions))
		{
			return false;
		}
		
		$notification_setting = $this->model('account')->get_notification_setting_by_uid($recipient_uid);
		
		//默认不认置则全部都发送
		if (empty($notification_setting['data']))
		{
			return true;
		}
		
		if (in_array($action_type, $notification_setting['data']))
		{
			return false;
		}
		else
		{
			return true;
		}
	}

	/**
	 * 
	 * 阅读段信息
	 * @param int $notification_id 信息id
	 * 
	 * @return array信息内容数组
	 */
	public function read_notification($notification_id)
	{
		$notify_info = $this->get_notification_by_ids($notification_id);
		
		if (empty($notify_info))
		{
			return false;
		}
		
		$unread_notifys = $this->get_unread_notification($this->user_id);
		
		if($unread_notifys)
		{
			$unread_extends = array();
			
			foreach($unread_notifys as $key => $val)
			{
				$unread_extends[$val['model_type']][$val['source_id']][] = $val;
			}
			
			$notifications = $unread_extends[$notify_info['model_type']][$notify_info['source_id']];
		}
		
		$notification_ids = array();
		
		if(empty($notifications))
		{
			$notification_ids[] = $notification_id;
		}
		else
		{
			foreach ($notifications as $key => $val)
			{
				$notification_ids[] = $val['notification_id'];
			}
		}
		
		$this->query("UPDATE " . get_table('notification') . " SET read_flag = notification_id WHERE notification_id IN (" . implode(",", array_unique($notification_ids)) . ")");
		
		$this->model('account')->increase_user_statistics(account_class::NOTIFICATION_UNREAD, 0, $this->user_id);
		
		return true;
	}

	/**
	 * 全部已读
	 */
	public function read_all($uid = 0)
	{
		if($uid == 0)
		{
			$uid = $this->user_id;
		}
		
		$this->query("UPDATE " . get_table('notification') . " SET read_flag = notification_id WHERE recipient_uid = " . $uid);
		
		$this->model("account")->increase_user_statistics(account_class::NOTIFICATION_UNREAD, 0, $uid);
		
		return true;
	}

	
	public function delete_notify($notification_id)
	{
		return $this->delete('notification', 'notification_id = ' . $notification_id);
	}

	/**
	 * 获取当前用户未读通知个数
	 * @param unknown_type $uid
	 * @return number
	 */
	function get_notifications_unread_num($uid = 0)
	{
		return $this->get_notification_list(true, $uid, '-1');
	}
	
	/**
	 * 获得用户通知列表
	 * @param unknown_type $count
	 * @param unknown_type $recipient_uid
	 * @param unknown_type $read_flag
	 * @param unknown_type $limit
	 * @return multitype:|number
	 */
	function get_notification_list($count = false, $recipient_uid = 0, $read_flag = '', $limit = '')
	{
		$where = array();
		
		$recipient_uid = intval($recipient_uid);
		
		if($recipient_uid == 0)
		{
			$recipient_uid = $this->user_id;
		}
		
		$where[] = 'recipient_uid = ' . $recipient_uid;
		
		switch($read_flag)
		{
			case '-1' : 
				$where[] = 'read_flag = 0';
				break;
			case '1' : 
				$where[] = 'read_flag > 0';
				break;
			case 'all' : 
				break;
			default:
				break;
		}
		
		$sql = "SELECT MAX(notification_id) notification_id FROM " . get_table('notification') . " WHERE " . implode(' AND ', $where) . " ";
		
		$sql .= "GROUP BY model_type, source_id, read_flag ORDER BY notification_id DESC";
		
		$rs = $this->query_all($sql, $limit);
		
		if(empty($rs))
		{
			if($count)
			{
				return 0;
			}
			else
			{
				return array();
			}
		}
		
		$notification_ids = array(); 
		
		foreach($rs as $val)
		{
			$notification_ids[] = $val['notification_id'];
		}
		
		$notification_ids = array_unique($notification_ids);
		
		if($count)
		{
			return count($notification_ids);
		}
		else
		{
			return $notification_ids;
		}
	}
	
	/**
	 * 获得用户未读合并通知
	 * @param unknown_type $count
	 * @param unknown_type $recipient_uid
	 * @param unknown_type $read_flag
	 * @param unknown_type $limit
	 * @return multitype:|number
	 */
	function get_unread_notification($recipient_uid)
	{
		$sql = "SELECT * FROM " . get_table('notification') . " WHERE recipient_uid = " . intval($recipient_uid) . " AND read_flag = 0 ORDER BY notification_id DESC";
		
		$rs = $this->query_all($sql);
		
		if(empty($rs))
		{
			return false;
		}
		
		foreach($rs as $key => $val)
		{
			$rs[$key]['data'] = unserialize($val['data']);
		}
		
		return $rs;
	}
	
	/**
	 * 根据通知ID集获得通知
	 * @param unknown_type $notifications_id
	 */
	function get_notification_by_ids($notification_id)
	{
		$notification_ids = array();
		
		if(is_array($notification_id))
		{
			$notification_ids = $notification_id;
		}
		else
		{
			$notification_ids[] = $notification_id;
		}
		
		if(empty($notification_ids))
		{
			return false;
		}

		$rs = $this->fetch_all('notification', "notification_id IN (" . implode(",", $notification_ids) . ')', 'notification_id DESC');
		
		if(empty($rs))
		{
			return false;
		}
		
		foreach($rs as $key => $val)
		{
			$rs[$key]['data'] = unserialize($val['data']);
		}
		
		if(is_array($notification_id))
		{
			return $rs;
		}
		else
		{
			return $rs[0];
		}
	}
	
}
